package com.lry.basic.spring.aop.core;

import com.lry.basic.spring.aop.face.MethodAfterAdvice;
import com.lry.basic.spring.aop.face.MethodAroundAdvice;
import com.lry.basic.spring.aop.face.MethodBeforeAdvice;

import java.lang.reflect.Method;
import java.util.List;

/**
 * @author:刘仁有
 * @desc:
 * @email:953506233@qq.com
 * @data:2019/11/8
 */
public class AopAdviceChainInvocation {
    private static Method invokeMethod;
    static{
        try {
            invokeMethod = AopAdviceChainInvocation.class.getMethod("invoke",null);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    private Object proxy;//cglib代理对象
    private Object target;//目标对象
    private Method method;//目标方法
    private Object[]args;////目标方法参数
    private List<Object> advices;//匹配到的advice
    public AopAdviceChainInvocation(Object proxy, Object target, Method method, Object[] args, List<Object> advices) {
        super();
        this.proxy = proxy;
        this.target = target;
        this.method = method;
        this.args = args;
        this.advices = advices;
    }

    private int i =0;
    public Object invoke() throws Exception {
        if(i<this.advices.size()){
            Object advice = this.advices.get(i++);
            if(advice instanceof MethodBeforeAdvice){
                ((MethodBeforeAdvice) advice).before(method, args, target);
            }else if(advice instanceof MethodAroundAdvice){
                return ((MethodAroundAdvice) advice).around(invokeMethod, null, this);
            }else if(advice instanceof MethodAfterAdvice){
                Object returnValue = this.invoke();
                ((MethodAfterAdvice) advice).after(returnValue, method, args, target);
                return returnValue;
            }
            return this.invoke();
        }else{
            return method.invoke(target,args);
        }
    }
}
